package com.lwg.vhr.config;

import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;

import java.util.Collection;

/**
 * @author: lwg
 * @Date: 2021/7/27 23:03
 * @Description: 判断当前登录的用户是否具备这个橘色
 */

@Component
public class CuestomHRRMyDecisionMannager implements AccessDecisionManager {

    /**
     *
     * @param authentication 当前登录的用户
     * @param object 请求对象
     * @param configAttributes 是CustomFilterInvocationSecurityMetadataSource类中的getAttributes方法的返回值
     * @throws AccessDeniedException
     * @throws InsufficientAuthenticationException
     */
    //很好比对，用户的角色在authentication里面，需要的角色在configAttributes里面，再区比较他们俩集合里面有没有包含关系就行
    @Override
    public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
        //遍历是CustomFilterInvocationSecurityMetadataSource类中返回的角色,一种匹配上。一种没有匹配上
        for (ConfigAttribute configAttribute : configAttributes) {
            //需要比对的角色
            String needRole = configAttribute.getAttribute();
            //如果需要的角色是"ROLE_LOGIN" 上个方法标记过的没有匹配到只需要登录的角色
            if ("ROLE_LOGIN".equals(needRole)) {
                //判断当前用户是否是匿名用户，是则未登录
                if (authentication instanceof AnonymousAuthenticationToken) {
                    throw new AccessDeniedException("尚未登录,请登录--------");
                } else { //如果为此角色,则直接返回,允许跳转
                    return;
                }
            }
            //如果是匹配上的角色，比对用户具备哪种角色
            //获取当前用户登录的角色
            Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
            for (GrantedAuthority authority : authorities) {
                if (authority.getAuthority().equals(needRole)) {
                    return;  //匹配用户的角色 直接返回，不需返回异常信息。
                }
            }

        }
        //两者都不满足，这说明既没有标记的，有咩有该角色
        throw new AccessDeniedException("权限不足，请联系管理员!");
    }

    @Override
    public boolean supports(ConfigAttribute configAttribute) {
        return true;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }
}
